#include "Utils.h"
#include <Windows.h>
#include <algorithm>

#include "SimpleBlobsLib.h"




std::vector<cv::Rect> Utils:: DetectBlobAgglomeration(const cv::Mat& im,int maxDistanceX, int maxDistanceY, int maxWidth, int maxHeight)
{
	Blobs::BlobList blobs;

	blobs.FindBlobs(im,0);

	blobs.MergeNearest(maxDistanceX,  maxDistanceY,  maxWidth,  maxHeight);

	auto blobRects = blobs.GetBlobRects();

	//cv::Mat mat = img.clone();
	//Utils::DrawObjectRects(blobRects,mat,127);

	return blobRects;
}

std::string Utils::GetApplicationDirectory()
{	
	char   fileName[255];
	if( GetModuleFileNameA(NULL,fileName,sizeof(fileName)) < 1 )
	{
		return NULL;
	}
	 

	std::string strFileName(fileName);

	int lastSlash = strFileName.find_last_of('\\');
	return strFileName.substr(0,lastSlash +1 );
}

std::string Utils::GetFileNameWithoutExtension(const std::string &filename)
{
	int lastDot = filename.find_last_of(".");
	int lastSlash = filename.find_last_of("\\");

	if(lastSlash > lastDot)//|| lastSlash <= 0)//se a ultima barra fica depois do ultimo ponto, significa que o arquivo nao tem extensao. Retorna o mesmo valor de entrada
	{
		return filename;
	}

	std::string res = filename.substr(lastSlash+1,lastDot-(lastSlash+1));
	return res ;

}

bool Utils::GetFilesInDirectory(const std::string directoryName,const std::string pattern,std::vector<std::string>&files)
{
	WIN32_FIND_DATAA fdFile; 
	HANDLE hFind = NULL; 

	files.clear();

	if((hFind = FindFirstFileA((directoryName + "\\"+ pattern).c_str(), &fdFile)) == INVALID_HANDLE_VALUE) 
	{ 
		return false; 
	} 

	do
	{ 
		if(strcmp(fdFile.cFileName, ".") != 0
		&& strcmp(fdFile.cFileName, "..") != 0) 
		{ 
			files.push_back((directoryName + "\\" + fdFile.cFileName).c_str());
		}
	} 
	while(FindNextFileA(hFind, &fdFile)); 

	FindClose(hFind); 
	return true; 		
}

bool Utils::DrawObjectRects(const std::vector<cv::Rect> &objs,cv::Mat& img,const int color)
{
	for (size_t  i = 0 ; i < objs.size() ;i++ )
	{
		const cv::Rect& rectRoi = objs[i];
		cv::rectangle(img,rectRoi,cv::Scalar(color));
		//image.drawRect(rectRoi.expand(1,1).fit(image.getRect()),color);
	}

	return true;
}

std::vector<cv::Point> Utils::GetVectorOfCenters(const std::vector<cv::Rect>&rects)
{
	std::vector<cv::Point> pts;
	pts.resize(rects.size());
	std::transform(rects.begin(),rects.end(),pts.begin(),[](const cv::Rect r){return cv::Point(r.x + r.width/2 +1, r.y + r.height/2 + 1);});

	return pts;
}